
.CODE

EXTRN CreateDreamInst : PROC

push_reg PROC
	;	must align for 16 bytes
	sub		rsp, 11*8 + 16 + 32
	mov		r10, rsp
	add		r10, 32+16
	;	128 bits align
	shr		r10, 4
	shl		r10, 4

	; fill rax
	mov qword ptr [r10+8*1], rbx	; rbx
	mov qword ptr [r10+8*2], rsi	; rsi
	mov qword ptr [r10+8*3], rdi	; rdi
	mov qword ptr [r10+8*4], rbp	; rbp
	mov rax, rsp
	add rax, 11*8 + 16 + 32 + 8
	mov qword ptr [r10+8*5], rax	; rsp
	mov qword ptr [r10+8*6], r12	; r12
	mov qword ptr [r10+8*7], r13	; r13
	mov qword ptr [r10+8*8], r14	; r14
	mov qword ptr [r10+8*9], r15	; r15
	mov rax, [rax-8]
	mov qword ptr [r10+8*0], rax	; rip
	STMXCSR	dword ptr[r10+8*10]		; mxcsr
IF	0
	movdqa	[r10+ (6+0)*10h], xmm8
	movdqa	[r10+ (6+1)*10h], xmm9
	movdqa	[r10+ (6+2)*10h], xmm10
	movdqa	[r10+ (6+3)*10h], xmm11
	movdqa	[r10+ (6+4)*10h], xmm12
	movdqa	[r10+ (6+5)*10h], xmm13
	movdqa	[r10+ (6+6)*10h], xmm14
	movdqa	[r10+ (6+7)*10h], xmm15
ENDIF
	mov rax, rcx
	mov rcx, r10
	call rax
	add rsp, 88h
	ret
push_reg ENDP

save_context PROC
	mov qword ptr [rcx+8*1], rbx	; rbx
	mov qword ptr [rcx+8*2], rsi	; rsi
	mov qword ptr [rcx+8*3], rdi	; rdi
	mov qword ptr [rcx+8*4], rbp	; rbp
	mov rax, rsp
	add rax, 08H
	mov qword ptr [rcx+8*5], rax	; rsp
	mov qword ptr [rcx+8*6], r12	; r12
	mov qword ptr [rcx+8*7], r13	; r13
	mov qword ptr [rcx+8*8], r14	; r14
	mov qword ptr [rcx+8*9], r15	; r15
	mov rax, qword ptr [rsp]
	mov qword ptr [rcx+8*0], rax	; rip
	STMXCSR dword ptr [rcx+8*10]	; MXCSR
	ret
save_context ENDP


pop_reg PROC
	;change stack frame
	mov rax, rdx
	mov rdx, qword ptr[rcx+8*0]
	mov rbx, qword ptr[rcx+8*1]
	mov rsi, qword ptr[rcx+8*2]
	mov rdi, qword ptr[rcx+8*3]
	mov rbp, qword ptr[rcx+8*4]
	mov rsp, qword ptr[rcx+8*5]
	mov r12, qword ptr[rcx+8*6]
	mov r13, qword ptr[rcx+8*7]
	mov r14, qword ptr[rcx+8*8]
	mov r15, qword ptr[rcx+8*9]
	LDMXCSR dword ptr [rcx+8*10]
	jmp rdx
pop_reg ENDP

run_with_stack PROC
	mov rax, rcx
	add rax, rdx
	;	must align for 16 bytes
	sub rax, 40h	;	32 bytes serserve space, rbp, rsp, [end]
	mov qword ptr[rax + 28h], rbp
	mov qword ptr[rax + 30h], rsp
	mov rsp, rax
	mov rbp, rax
	mov rcx, r9
	call r8
	mov rbp, [rsp + 28h]
	mov rsp, [rsp + 30h]
	ret
run_with_stack ENDP


get_stack PROC
	mov rax, rsp
	add rax, 8
	ret
get_stack ENDP


;lolix::LOLIX_RETNV
;lxsamsara::_inst::recurrence_inst::dream(lxsamsara::dream** out_ptr)const
;rcx->this, rdx->out_ptr
?nap@recurrence_inst@_inst@lxsamsara@@UEBA?AW4LOLIX_RETNV@lolix@@PEAPEAVdream@3@@Z PROC
	sub		rsp, 88		;_RegBack$Size
	push	rcx
	push	rdx
	lea		rcx, [rsp+16]
	call	save_context
	pop		rcx							; CreateDreamInst:out_ptr
	pop		rdx							; CreateDreamInst:rinst
	mov		rax, qword ptr [rsp + 88]
	mov		qword ptr [rsp], rax		; eip
	lea		rax, [rsp + 96]
	mov		qword ptr [rsp + 40], rax	; esp

	;extern "C" lolix::LOLIX_RETNV
	;CreateDreamInst(lxsamsara::dream** out_ptr, lxsamsara::_inst::recurrence_inst* rinst, _RegBack const* regBack)

	mov		r8, rsp						;	CreateDreamInst:regBack
	sub		rsp, 20h
	call	CreateDreamInst
	add		rsp, 20h
	ret		88

?nap@recurrence_inst@_inst@lxsamsara@@UEBA?AW4LOLIX_RETNV@lolix@@PEAPEAVdream@3@@Z ENDP

END
